#include <ESP8266WiFi.h>   //安装esp8266arduino开发环境
#include <PubSubClient.h>  //安装PubSubClient库
#include <ArduinoJson.h>   //json  V5版本
#include "aliyun_mqtt.h"
//需要安装crypto库

#include "DHT11.h"
#include <Servo.h>

Servo myservo; 
DHT11 DHT11(D0);


#define LED     D4
const int ADC0 = A0;  // Analog input pin that the potentiometer is attached to
#define WIFI_SSID        "jetbot"//替换自己的WIFI
#define WIFI_PASSWD      "12345678"//替换自己的WIFI

#define PRODUCT_KEY      "a1BYDzKeW25" //替换自己的PRODUCT_KEY
#define DEVICE_NAME      "bilibili" //替换自己的DEVICE_NAME
#define DEVICE_SECRET    "1573cc09e32d4a38ce729e1c923758ec"//替换自己的DEVICE_SECRET

#define DEV_VERSION       "S-TH-WIFI-v1.0-20190220"        //固件版本信息

#define ALINK_BODY_FORMAT         "{\"id\":\"123\",\"version\":\"1.0\",\"method\":\"%s\",\"params\":%s}"
#define ALINK_TOPIC_PROP_POST     "/sys/" PRODUCT_KEY "/" DEVICE_NAME "/thing/event/property/post"
#define ALINK_TOPIC_PROP_POSTRSP  "/sys/" PRODUCT_KEY "/" DEVICE_NAME "/thing/event/property/post_reply"
#define ALINK_TOPIC_PROP_SET      "/sys/" PRODUCT_KEY "/" DEVICE_NAME "/thing/service/property/set"
#define ALINK_METHOD_PROP_POST    "thing.event.property.post"
#define ALINK_TOPIC_DEV_INFO      "/ota/device/inform/" PRODUCT_KEY "/" DEVICE_NAME ""    
#define ALINK_VERSION_FROMA      "{\"id\": 123,\"params\": {\"version\": \"%s\"}}"
unsigned long lastMs = 0;

WiFiClient   espClient;
PubSubClient mqttClient(espClient);

int humi = 0 , temp = 0, light = 0, co2 = 0;

void init_wifi(const char *ssid, const char *password)      //连接WiFi
{
    WiFi.mode(WIFI_STA);
    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED)
    {
        Serial.println("WiFi does not connect, try again ...");
        delay(500);
    }

    Serial.println("Wifi is connected.");
    Serial.println("IP address: ");
    Serial.println(WiFi.localIP());
}

void mqtt_callback(char *topic, byte *payload, unsigned int length) //mqtt回调函数
{
    Serial.print("Message arrived [");
    Serial.print(topic);
    Serial.print("] ");
    payload[length] = '\0';
    Serial.println((char *)payload);
   // https://arduinojson.org/v5/assistant/  json数据解析网站

        
    Serial.println("   ");
    Serial.println((char *)payload);
    Serial.println("   ");
    if (strstr(topic, ALINK_TOPIC_PROP_SET))
    {
        StaticJsonBuffer<100> jsonBuffer;
        JsonObject &root = jsonBuffer.parseObject(payload);
        int params_switch_hot    = root["params"]["switch_hot"];
        int params_switch_water  = root["params"]["switch_water"];
        int params_switch_fan    = root["params"]["switch_fan"];
        int params_switch_window = root["params"]["switch_window"];
        if(params_switch_hot==1)
        {Serial.println("led1 off");
        digitalWrite(D1, HIGH); 
        myservo.write(90); 
        }
        else
        {Serial.println("led1 on");
        digitalWrite(D1, LOW); 
        myservo.write(0); }
       

       if(params_switch_water==1)
        {Serial.println("led2 off");
        digitalWrite(D2, HIGH); 
        }
        else
        {Serial.println("led2 on");
        digitalWrite(D2, LOW); }
        

        
          if(params_switch_fan==1)
        {Serial.println("led3 off");
        digitalWrite(D3, HIGH); 
        }
        else
        {Serial.println("led3 on");
        digitalWrite(D3, LOW); }
       

         if(params_switch_window==1)
        {Serial.println("led4 off");
        digitalWrite(D4, HIGH); 
        }
        else
        {Serial.println("led4 on");
        digitalWrite(D4, LOW); }
        if (!root.success())
        {
            Serial.println("parseObject() failed");
            return;
        }
        
    }
}
/*
void switch_button(int params_switch , void Dx)
{
         if(params_switch==1)
        {Serial.println("led4 off");
        digitalWrite(Dx, HIGH); 
        }
        else
        {Serial.println("led4 on");
        digitalWrite(Dx, LOW); }
  }
*/
void mqtt_version_post()
{
    char param[512];
    char jsonBuf[1024];

    //sprintf(param, "{\"MotionAlarmState\":%d}", digitalRead(13));
    sprintf(param, "{\"id\": 123,\"params\": {\"version\": \"%s\"}}", DEV_VERSION);
   // sprintf(jsonBuf, ALINK_BODY_FORMAT, ALINK_METHOD_PROP_POST, param);
    Serial.println(param);
    mqttClient.publish(ALINK_TOPIC_DEV_INFO, param);
}
void mqtt_check_connect()
{
    while (!mqttClient.connected())//
    {
        while (connect_aliyun_mqtt(mqttClient, PRODUCT_KEY, DEVICE_NAME, DEVICE_SECRET))
        {
            Serial.println("MQTT connect succeed!");
            //client.subscribe(ALINK_TOPIC_PROP_POSTRSP);
            mqttClient.subscribe(ALINK_TOPIC_PROP_SET);
            
            Serial.println("subscribe done");
            mqtt_version_post();
        }
    }
    
}

void mqtt_interval_post()
{
    char param[512];
    char jsonBuf[1024];

    //sprintf(param, "{\"MotionAlarmState\":%d}", digitalRead(13));
    sprintf(param, "{\"switch_hot\":%d,\"switch_water\":%d,\"switch_fan\":%d,\"switch_window\":%d,\"light\":%d,\"co2\":%d,\"humi\":%d,\"temp\":%d}", \
    !digitalRead(D1),!digitalRead(D2),!digitalRead(D3),!digitalRead(D4),random(150,300) , co2, random(70,90) , random(20,25));
    Serial.println(param);
    
    sprintf(jsonBuf, ALINK_BODY_FORMAT, ALINK_METHOD_PROP_POST, param);
    Serial.println(jsonBuf);
    mqttClient.publish(ALINK_TOPIC_PROP_POST, jsonBuf);
}


void setup()
{

   
    
    pinMode(LED, OUTPUT);
    pinMode(D1, OUTPUT);
    pinMode(D2, OUTPUT);
    pinMode(D3, OUTPUT);
    myservo.attach(D7);
    /* initialize serial for debugging */
    Serial.begin(115200);

    Serial.println("Demo Start");

    init_wifi(WIFI_SSID, WIFI_PASSWD);

    mqttClient.setCallback(mqtt_callback);
}

// the loop function runs over and over again forever
void loop()
{
      
    if (millis() - lastMs >= 5000)  //5S
    {
        lastMs = millis();
        mqtt_check_connect();
        /* Post */   
        co2 = analogRead(ADC0);  
     Serial.print("二氧化碳：");
    Serial.println(co2);    
        mqtt_interval_post();
    }
   
   
    mqttClient.loop();

   
}
